package com.jf.net.utils

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.wifi.WifiManager
import android.telephony.TelephonyManager
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.net.UnknownHostException
import java.util.Locale
import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import java.util.concurrent.Executors

/**
 * NetUtils
 * @author JackyFlame
 * @time 2023/10/20 15:09
 * @description
 */
class NetUtils private constructor() {

    enum class NetworkType {
        NETWORK_WIFI, NETWORK_4G, NETWORK_3G, NETWORK_2G, NETWORK_UNKNOWN, NETWORK_NO
    }

    companion object {

        /**
         * 获取活动网络信息
         */
        private val connectivityManager: ConnectivityManager
            get() {
                return AppUtil.getAppContext()
                    .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            }

        /**
         * 获取活动网络信息
         */
        private val networkCapabilities: NetworkCapabilities?
            get() {
                return connectivityManager.let { cm->
                    cm.activeNetwork?.let {
                        cm.getNetworkCapabilities(it)
                    }
                }
            }

        /**
         * 获取活动网络信息
         */
        private val activeNetwork: Network?
            get() {
                val cm = AppUtil.getAppContext()
                    .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                return cm.activeNetwork
            }

        /**
         * 判断网络是否连接
         */
        val isConnected: Boolean
            get() {
                return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
            }

        /**
         * 判断网络是否是蜂窝网络
         */
        fun isCellular (): Boolean {
            return networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ?: false
        }

        /**
         * 判断wifi是否打开
         * 打开或关闭wifi
         *
         * @param enabled
         */
        @Suppress("DEPRECATION")
        var wifiEnabled: Boolean
            get() {
                val wifiManager =
                    AppUtil.getAppContext().applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
                return wifiManager.isWifiEnabled
            }
            set(enabled) {
                val wifiManager =
                    AppUtil.getAppContext().applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
                if (enabled) {
                    if (!wifiManager.isWifiEnabled) {
                        wifiManager.isWifiEnabled = true
                    }
                } else {
                    if (wifiManager.isWifiEnabled) {
                        wifiManager.isWifiEnabled = false
                    }
                }
            }

        /**
         * 判断wifi是否连接状态
         */
        val isWifiConnected: Boolean
            get() {
                return networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ?: false
            }

        /**
         * 获取网络运营商名称 中国移动、如中国联通、中国电信
         *
         * @return 运营商名称
         */
        val networkOperatorName: String?
            get() {
                val tm = AppUtil.getAppContext()
                    .getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                return tm.networkOperatorName
            }
        private const val NETWORK_TYPE_GSM = 16
        private const val NETWORK_TYPE_TD_SCDMA = 17
        private const val NETWORK_TYPE_IWLAN = 18

        /**
         * 获取IP地址
         *
         * @param useIPv4 是否用IPv4
         * @return IP地址
         */
        @ExperimentalStdlibApi
        fun getIPAddress(useIPv4: Boolean): String? {
            try {
                val nis = NetworkInterface.getNetworkInterfaces()
                while (nis.hasMoreElements()) {
                    val ni = nis.nextElement()
                    // 防止小米手机返回10.0.2.15
                    if (!ni.isUp) {
                        continue
                    }
                    val addresses = ni.inetAddresses
                    while (addresses.hasMoreElements()) {
                        val inetAddress = addresses.nextElement()
                        if (inetAddress != null && !inetAddress.isLoopbackAddress) {
                            val hostAddress = inetAddress.hostAddress ?: return null
                            val isIPv4 = hostAddress.indexOf(':') < 0
                            if (useIPv4) {
                                if (isIPv4) return hostAddress
                            } else {
                                if (!isIPv4) {
                                    val index = hostAddress.indexOf('%')
                                    return if (index < 0) {
                                        hostAddress.uppercase(Locale.getDefault())
                                    } else {
                                        hostAddress.substring(0, index).uppercase(Locale.getDefault())
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (e: SocketException) {
                e.printStackTrace()
            }
            return null
        }

        /**
         * 获取域名ip地址
         *
         * @param domain 域名
         * @return ip地址
         */
        fun getDomainAddress(domain: String?): String? {
            try {
                val exec = Executors.newCachedThreadPool()
                val fs = exec.submit(Callable {
                    val inetAddress: InetAddress
                    try {
                        inetAddress = InetAddress.getByName(domain)
                        return@Callable inetAddress.hostAddress
                    } catch (e: UnknownHostException) {
                        e.printStackTrace()
                    }
                    null
                })
                return fs.get()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            } catch (e: ExecutionException) {
                e.printStackTrace()
            }
            return null
        }
    }
}